import { Avatar, AvatarColumns, avatars, avatar_parts } from "@/core/avatar"
import { Character, DealerType } from "@/core/character"
import { Equip, EquipColumns, equip_parts, findEquipBySuit } from "@/core/equips"
import { createItems, Emblem, Enchant, ItemSlot, rateItem, toItems } from "@/core/item"

import createSlots from "@/core/slots"
import { defineStore } from "pinia"
import { CharacterList, character_list } from "@/core/alter"
import { Siroco } from "@/core/sirocos"
import { Ozma } from "@/core/ozmas"
import { createPetColumn, Pet, PetColumn } from "@/core/pets/pet"
import emblems from "@/core/emblems"
import enchants from "@/core/enchants"
import { useCalcStore, useConfigStore } from "."
import { debounce } from "lodash"
import pets from "@/core/pets"
import { Skill } from "@/core/skill"

interface BaseSetting {
    adventurer_level: number
    guild_buff: boolean
    apc: ApcSetting
    dungeon_buff: "ozma" | "siroco"
    wedding_ring: number
}

interface ApcSetting {
    intstr: number
    attack: number
    type: DealerType
}

export interface CharacterState {
    character?: Character
    character_level: number
    character_list: CharacterList
    equip_columns: EquipColumns
    pet_column: PetColumn
    avatar_columns: AvatarColumns
    siroco_columns: (Siroco | undefined)[]
    ozma_columns: (Ozma | undefined)[]
    talismans_columns: number[]
    base_setting: BaseSetting
    damage_buffer: boolean //辅助职业单人属性
}

export const useCharacterStore = defineStore("character", {
    state(): CharacterState {
        return {
            character_list,
            character_level: 100,
            equip_columns: {},
            avatar_columns: {},
            pet_column: createPetColumn(),
            siroco_columns: [undefined, undefined, undefined],
            ozma_columns: [undefined, undefined, undefined, undefined, undefined],
            talismans_columns: [1, 2, 3],
            base_setting: {
                adventurer_level: 40,
                guild_buff: true,
                wedding_ring: 1,
                apc: {
                    type: "phyatk",
                    intstr: 5000,
                    attack: 3000
                },
                dungeon_buff: "ozma"
            },
            damage_buffer: false
        }
    },
    getters: {
        using_equips() {
            const equips: Equip[] = []
            for (let key in this.equip_columns) {
                const column = this.equip_columns[key]
                if (!!column.item) {
                    equips.push(column.item)
                }
            }

            return equips
        },
        enchant_list(): Enchant[] {
            return createItems(enchants).filter(rateItem)
        },
        emblem_list(): Emblem[] {
            return createItems(emblems).filter(rateItem)
        },
        avatar_list() {
            return avatars.map(e => {
                let { options } = e
                options = toItems(options)
                return {
                    ...e,
                    options
                } as Avatar
            })
        },
        skills(): Skill[] {
            return this.character?.skills.map(e => e.skill) ?? []
        }
    },
    actions: {
        setDamageBuffer(value: boolean) {
            this.damage_buffer = !!this.character?.is_buffer && value
        },

        setOzma(index: number, ozma?: Ozma) {
            this.ozma_columns[index] = ozma
        },
        clarOzma() {
            this.ozma_columns = this.ozma_columns.map(e => undefined)
        },

        setSiroco(index: number, siroco?: Siroco) {
            this.siroco_columns[index] = siroco
        },

        setEquipSuit(suit_name: string) {
            if (this.character) {
                const equips = findEquipBySuit(suit_name)
                for (let equip of equips) {
                    this.setEquip(equip.part, equip)
                }
            }
        },

        setEquip(part: string, equip?: Equip) {
            const column = this.equip_columns[part]
            if (column) {
                column.item = equip
            }
        },

        setAvatar(part: string, avatar?: Avatar) {
            const column = this.avatar_columns[part]
            if (column) {
                column.item = avatar
            }
        },

        setAvatarSuit(suit_name: string) {
            if (!this.character) {
                return
            }
            const avatars = this.avatar_list.filter(e => e.suit_name == suit_name)
            for (let avatar of avatars) {
                this.setAvatar(avatar.part, avatar)
            }
        },

        newCharacter(name: string) {
            if (!this.character_list[name]) {
                throw new Error(`not found character by ${name}.`)
            }
            const character = new Character(character_list[name])
            this.equip_columns = createEquipColumns(character)
            this.avatar_columns = createAvatarColumns()
            this.character = character
            const calcStore = useCalcStore()

            const config = useConfigStore()
            config.load(this.character?.alter)

            this.$subscribe(
                debounce(async () => {
                    config.save(this.character?.alter)
                    await calcStore.calculate_self()
                }, 20)
            )

            this.setPet(pets[0])
            return character
        },

        setColumnData(part: string, key: string, value: any) {
            const column = this.equip_columns[part]
            if (column) {
                column.data.set(key, value)
            }
        },

        getColumnData(part: string, key: string) {
            const column = this.equip_columns[part]
            if (column) {
                return column.data.get(key)
            }
        },

        setPet(pet: Pet) {
            this.pet_column.item = pet
        }
    }
})

function createEquipColumns(character?: Character) {
    let columns: EquipColumns = {}
    for (let part of equip_parts) {
        const slots: ItemSlot[] = []
        for (let createSlot of createSlots) {
            const slot = createSlot(part)
            if (!!slot) {
                slots.push(slot)
            }
        }
        const data = new Map<string, any>()
        if (part == "weapon") {
            data.set("refine_level", 8)
        }
        data.set("has_cursed", true)
        data.set("upgrade_level", part == "earrings" ? 12 : 10)
        data.set("adapt_status", character?.adapt_status)
        data.set("armor_type", character?.armor_type)
        columns[part] = { part, slots, data }
    }

    return columns
}

function createAvatarColumns() {
    let columns: AvatarColumns = {}
    for (let part of avatar_parts) {
        const slots: ItemSlot[] = []
        const data = new Map<string, any>()
        columns[part] = { part, slots, data }
    }
    return columns
}

export function getSkillImg(name: string) {
    const { character } = useCharacterStore()
    if (character) {
        const { job, alter } = character
        name = name.replace(`${job}.${alter}.`, `${alter}/skill/`)
        return `/resources/${name}.png`
    }
    return ""
}
